package fortunata.fswapps.vpoet;

import java.net.*;

/**
 *
 */
public class VPOETRequestData {
        public String valAction;
        public String valOntoElemID;
        public String valDesignID;
        public String valOutFormat;
        //public String valDesignType;
        public String valSource;
        public String valProvider;
        public String valIndividualID;
        private boolean isValid;
        protected URL initialRequest;
        public static String paramNameAction = "action";
        public static String paramNameOntoElemID = "object";
        public static String paramNameOutFormat = "outformat";
        public static String paramNameProvider = "provider";
        public static  String paramNameDesignID = "designID";
        public static String paramNameSource = "source";
        public static String paramNameIndvID = "indvID";
        public static String paramValueInput = "input";
        public static String paramValueOutput = "output";
        public static String paramValueRenderInput = "renderInput";
        public static String paramValueRenderOutput = "renderOutput";
        
     public VPOETRequestData(String url){
         isValid = false;
         try {
             initialRequest = new URL(url);
         }catch(MalformedURLException e){
            //TODO
         }

     }
     boolean isValid(){
         return isValid;
     }
     public String getRequestForRelation(String source, String ontoElemID, String individualID){
        String reqStr= initialRequest.toString();
        String valSource = hasParameter(reqStr, paramNameSource)? getParameter(reqStr, paramNameSource) : "";
        String valOntoElem = hasParameter(reqStr, paramNameOntoElemID)? getParameter(reqStr, paramNameOntoElemID) : "";
        String valIndvID = hasParameter(reqStr, paramNameIndvID)? getParameter(reqStr, paramNameIndvID) : "";

        String str1 = substitute(reqStr, valSource, source);
        String str2 = substitute(str1, valOntoElem, ontoElemID);
        String str3 = substitute(str2, valIndvID, individualID);
        return str3;
     }
      public String getRequestForIndividual(String individualURI){
       String reqStr= initialRequest.toString();
       if (hasParameter(reqStr, paramNameIndvID)){
            reqStr = substitute(reqStr,
                                paramNameIndvID + "=" + getParameter(reqStr, paramNameIndvID),
                                paramNameIndvID + "=" + individualURI);
       }else{
           reqStr = reqStr + "&" + paramNameIndvID + "=" + individualURI;
       }
       if (hasParameter(reqStr, paramNameSource)){
           reqStr = substitute(reqStr,
                               paramNameSource + "=" + getParameter(reqStr, paramNameSource),
                               paramNameSource + "=" + individualURI);
       }else{
           reqStr = reqStr + "&" + paramNameSource + "=" + individualURI;
       }
       return reqStr;
    }

    /**
     * @param individualURI This uri can be encoded
     * @return
     * @throws URISyntaxException
     */
     public String getRequestForSource(String individualURI) throws Exception {
        String reqStr= initialRequest.toString();
        if (hasParameter(reqStr, paramNameIndvID)){ //It it specifies the individual-->Remove the individual
             reqStr = substitute(reqStr,
                                 "?"+paramNameIndvID + "=" + getParameter(reqStr, paramNameIndvID),
                                 "");
        }
        URI uri = null;
        String computedSource = null;
        try {
            String decodedUriStr = URLDecoder.decode(individualURI, "UTF-8");
            uri = new URI(decodedUriStr);
            String fragment = uri.getFragment();
            if (fragment != null){
                int idxFrag = decodedUriStr.lastIndexOf(fragment);
                computedSource = decodedUriStr.substring(0, idxFrag - 1); //-1 to remove the #
            }else{
                computedSource = decodedUriStr;
            }
        }catch(Exception e){
            throw e;
        }
        if (hasParameter(reqStr, paramNameSource)){
            reqStr = substitute(reqStr, getParameter(reqStr, paramNameSource), computedSource);
        }else{
            reqStr = reqStr + "&" + paramNameSource + "=" + computedSource;
        }
        return reqStr;
     }
    /**
     * Only substitutes the fist ocurrence
     * @param strIn
     * @param from
     * @param to
     * @return  the initial string with the susbtitution
     */
     static protected String substitute(String strIn, String from, String to){
         StringBuffer sb = new StringBuffer();
         int idxFromStr = strIn.indexOf(from);
         if (idxFromStr != -1){
             sb.append(strIn.substring(0, idxFromStr));
         }else{
             return strIn;
         }
         sb.append(to);
         sb.append(strIn.substring(idxFromStr + from.length()));
         strIn = sb.toString();
         return strIn;
     }
     protected static boolean hasParameter(String reqStr, String paramName){
        return (reqStr.toString().indexOf(paramName) != -1)? true: false;
     }

    /**
     * For debug proposes
     * @param vpoetReq
     * @return
     */
     protected String niceDisplay (String vpoetReq){
         String[] parts = vpoetReq.split("&");
         StringBuffer sb = new StringBuffer();
         for (int i = 0; i < parts.length; i++){
            if (i > 0){
                sb.append("&");
            }
            sb.append(parts[i] + "\n");
         }
         return sb.toString();
     }

    /**
     * Assumes that the parameter exists and that this can have value "". Use hasParameter before use this method.
     * @param paramName
     * @return
     */
     protected static String getParameter(String reqStr, String paramName){
        String urlStr = reqStr.toString();
        int idxParamPair = urlStr.indexOf(paramName);
        String rest = urlStr.substring(idxParamPair);
        String pairStr = null;
        if (rest.indexOf("&") != -1){ //There are no other parameter on the right
            pairStr = rest.substring(0, rest.indexOf("&"));
        }else{ //This is the last parameter
            pairStr = rest;
        }
        String[] parts = pairStr.split("=");
        return (parts.length == 2)? parts[1]: "";
     }

     static public void main(String[] args){
           String urlStr1 = "http://localhost/fortunata/servlet/VPoetRequestServlet?action=renderOutput"+
                           "&designID=SimpleFOAFOutputConditional"+
                           "&provider=mra68"+
                           "&source=http://www.w3.org/People/Berners-Lee/card";
           VPOETRequestData r = new VPOETRequestData(urlStr1);
//           r.getRequestForRelation("http://www.ii.uam.es/~mrico/foaf.rdf",
//                                   "",
//                                   ""
//                                   );
          System.out.println("Original request:\n" + r.niceDisplay(urlStr1));
          String idvStr1 = "http%3A%2F%2Fdbpedia.org%2Fresource%2FTim_Bray";
          String res1 = r.getRequestForIndividual(idvStr1);
          System.out.println("After getRequestForIndividual("+ idvStr1 +"):\n" + r.niceDisplay(res1));

          String urlStr2 = "http://localhost/fortunata/servlet/VPoetRequestServlet?action=renderOutput"+
                           "&designID=SimpleFOAFOutputConditional"+
                           "&provider=mra68"+
                           "&source=http://www.w3.org/People/Berners-Lee/card" +
                           "&indvID=http%3A%2F%2Fwww.w3.org%2FPeople%2FBerners-Lee%2Fcard%23i";

          System.out.println("Original request:\n" + r.niceDisplay(urlStr2));
          try {
             String idvStr2 = "http%3A%2F%2Fhometown.aol.com%2Fchbussler%2Ffoaf%2Fchbussler.foaf%23me";
             String res2 = r.getRequestForSource(idvStr2);
             System.out.println("After getRequestForSource("+ idvStr2+ "):\n" + r.niceDisplay(res2));
          }catch(Exception e){
              System.out.println("Wrong URI!");
          }

     }
}

